from django.template import Context, loader
from todo.models import Task, Person
from django.http import HttpResponse, HttpResponseServerError
from google.appengine.api import users
import logging
from google.appengine.ext import db
import simplejson

def select(test, list):  
    selected = None 
    for item in list:  
        if test(item) == True:  
            selected = item  
            break;  
    return selected

def tasks(person_id):
    person_query = Person.all().filter('container_user_id = ', person_id)
    person = person_query.get()
    my_task_query = Task.all().filter('created_by = ', person)
    all_tasks = my_task_query.fetch(100)
    assigned_task_query = Task.all().filter('assigned_to = ', person)
    assigned_tasks = assigned_task_query.fetch(100)
    combined_tasks = []
    combined_tasks.extend(all_tasks)
    combined_tasks.extend(assigned_tasks)

    #group tasks by status
    working_on_task = select(lambda x: x.isInProgress() and x.isOwnedBy(person), combined_tasks)    
    paused_tasks = filter(lambda x: x.isPaused() and x.isOwnedBy(person), combined_tasks)
    completed_tasks = filter(lambda x: x.isComplete() and x.isOwnedBy(person), combined_tasks)    
    delegated_tasks = filter(lambda x: x.isDelegatedBy(person), combined_tasks)
    
    tasks_for_output = {}    
    #convert task objects to serialization friendly dict's
    if working_on_task != None:
        tasks_for_output["inprogress"] = [working_on_task.to_dict()]
    
    if len(paused_tasks) > 0:
        paused_tasks_to_dict = []
        for task in paused_tasks:
            paused_tasks_to_dict.append(task.to_dict())
        tasks_for_output["paused"] = paused_tasks_to_dict    
        
    if len(completed_tasks) > 0:
        completed_tasks_to_dict = []
        for task in completed_tasks:
            completed_tasks_to_dict.append(task.to_dict())
        tasks_for_output["completed"] = completed_tasks_to_dict   
        
    if len(delegated_tasks) > 0:
        delegated_tasks_to_dict = []
        for task in delegated_tasks:
            delegated_tasks_to_dict.append(task.to_dict())
        tasks_for_output["delegated"] = delegated_tasks_to_dict 

    return tasks_for_output

def ensure_user(user_id):
    person = Person.gql("WHERE container_user_id = :1", user_id).get()
    if(person is None):
        person = Person(container_user_id=user_id)
    person.put()
    return person
    
def get_tasks(request,person_container_id):    
    return HttpResponse(simplejson.dumps(tasks(person_container_id)))

def add_task(request):
    person_id = request.POST["id"]
    person = Person.gql("WHERE container_user_id = :1", person_id).get()
    if(person is None):
        person = Person(container_user_id=person_id)
    person.put()
    task = Task(name=request.POST["name"], created_by=person)
    task.put()
    task.task_id = task.key().id()
    task.put()
    return HttpResponse(simplejson.dumps(tasks(person_id)))

def add_task_get(request):
    person_id = request.GET["id"]
    person = Person.gql("WHERE container_user_id = :1", person_id).get()
    if(person is None):
        person = Person(container_user_id=person_id)
    person.put()
    task = Task(name=request.GET["name"], created_by=person)
    task.put()
    task.task_id = task.key().id()
    task.put()
    return HttpResponse(simplejson.dumps(tasks(person_id)))

def start_task(request):   
    task = Task.gql("WHERE task_id = :1", int(request.POST["task_id"])).get()
    #paused_task = Task.get_by_id(int(task_id))
    if task is None:
        return HttpResponseServerError("Could not find paused task with id=%d", request.POST["task_id"]) 
    #determine who's the current task "owner"
    person = task.created_by
    if(task.assigned_to != None):
        person = task.assigned_to
    created_by_task_query = Task.all().filter('created_by = ', person)
    assigned_to_task_query = Task.all().filter('assigned_to = ', person)    
    if(not task.isInProgress()):            
        #pause task in progress if any 
        my_tasks = created_by_task_query.fetch(100)
        assigned_tasks = assigned_to_task_query.fetch(100)
        my_tasks.extend(assigned_tasks)
        working_on_task = select(lambda x: x.isInProgress(), my_tasks) 
        if(working_on_task != None):
            working_on_task.pause(1) 
        task.start()
    #render tasks for current owner
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))
    
def start_task_get(request):
    task = Task.gql("WHERE task_id = :1", int(request.GET["task_id"])).get()
    #paused_task = Task.get_by_id(int(task_id))
    if task is None:
        return HttpResponseServerError("Could not find paused task with id=%d", request.GET["task_id"]) 
    #determine who's the current task "owner"
    person = task.created_by
    task_query = Task.all().filter('created_by = ', person)    
    if(task.assigned_to != None):
        person = task.assigned_to
        task_query = Task.all().filter('assigned_to = ', person)
    if(not task.isInProgress()):            
        #pause task in progress if any 
        all_tasks = task_query.fetch(100)
        working_on_task = select(lambda x: x.isInProgress(), all_tasks) 
        if(working_on_task != None):
            working_on_task.pause(1) 
        task.start()
    #render tasks for current owner
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))
    
def pause_task(request):
    task = Task.gql("WHERE task_id = :1", int(request.POST["task_id"])).get()
    #paused_task = Task.get_by_id(int(task_id))
    if task is None:
        return HttpResponseServerError('Could not find task with id=%d', task_id)
    task.pause(1)  
    person = task.created_by  
    if(task.assigned_to != None):
        person = task.assigned_to     
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))    

def pause_task_get(request):
    task = Task.gql("WHERE task_id = :1", int(request.GET["task_id"])).get()
    #paused_task = Task.get_by_id(int(task_id))
    if task is None:
        return HttpResponseServerError('Could not find task with id=%d', task_id)
    task.pause(1)  
    person = task.created_by  
    if(task.assigned_to != None):
        person = task.assigned_to     
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))   

def assign_task(request):   
    task = Task.gql("WHERE task_id = :1", int(request.POST["task_id"])).get()
    if task is None:
        return HttpResponseServerError('Could not find task') 
    current_owner = task.created_by  
    if(task.assigned_to != None):
        current_owner = task.assigned_to
    assignee = ensure_user(request.POST["assign_to"])       
    task.assign(assignee)
    return HttpResponse(simplejson.dumps(tasks(request.POST["viewer_id"])))
    
def assign_task_get(request):
    task = Task.gql("WHERE task_id = :1", int(request.GET["task_id"])).get()
    if task is None:
        return HttpResponseServerError('Could not find task') 
    current_owner = task.created_by  
    if(task.assigned_to != None):
        current_owner = task.assigned_to
    assignee = ensure_user(request.GET["assign_to"])       
    task.assign(assignee)
    return HttpResponse(simplejson.dumps(tasks(request.GET["viewer_id"])))

def complete_task(request):   
    task = Task.gql("WHERE task_id = :1", int(request.POST["task_id"])).get()
    if task is None:
        return HttpResponseServerError('Could not find task with id=%d', task_id)            
    task.complete()
    person = task.created_by  
    if(task.assigned_to != None):
        person = task.assigned_to
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))
    
def complete_task_get(request):
    task = Task.gql("WHERE task_id = :1", int(request.GET["task_id"])).get()
    if task is None:   
        return HttpResponseServerError('Could not find task with id=%d', task_id)     
    task.complete()
    person = task.created_by  
    if(task.assigned_to != None):
        person = task.assigned_to
    return HttpResponse(simplejson.dumps(tasks(person.container_user_id)))
    